package info.liujiachen.test.spring.security.service;

import info.liujiachen.test.spring.security.entity.JwtUser;
import info.liujiachen.test.spring.security.entity.JwtUserAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.factory.PasswordEncoderFactories;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

@Service
public class JwtUserDetailsService implements UserDetailsService {

    private static List<JwtUser> users = new ArrayList<>();

    public JwtUserDetailsService() {
        List<JwtUserAuthority> userAuthorities = new ArrayList<>();
        userAuthorities.add(new JwtUserAuthority("info"));
        userAuthorities.add(new JwtUserAuthority("current"));
        JwtUser user = new JwtUser("user", "123456", userAuthorities);
        users.add(user);
        List<JwtUserAuthority> guestAuthorities = new ArrayList<>();
        guestAuthorities.add(new JwtUserAuthority("info"));
        JwtUser guest = new JwtUser("guest", "123456", guestAuthorities);
        users.add(guest);
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        JwtUser jwtUser = findUser(username);
        if (Optional.ofNullable(jwtUser).isPresent()) {
            PasswordEncoder encoder = PasswordEncoderFactories.createDelegatingPasswordEncoder();
            return User.builder().username(jwtUser.getUsername()).password(encoder.encode(jwtUser.getPassword())).authorities(jwtUser.getAuthorities()).build();
        } else {
            throw new UsernameNotFoundException("User Not Found");
        }
    }

    public JwtUser findUser(String username) {
        JwtUser jwtUser = null;
        if (Optional.ofNullable(username).isPresent()) {
            for(JwtUser user : this.users) {
                if (user.getUsername().equals(username)) {
                    jwtUser = user;
                    break;
                }
            }
        }
        return jwtUser;
    }

}
